﻿using Microsoft.VisualStudio.Diagrams.View;
using Microsoft.VisualStudio.GraphModel;
using Microsoft.VisualStudio.Progression;
using Microsoft.VisualStudio.Progression.Controls;
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace Timtopia.DGMLPosterView
{
    public class PosterViewVisualFactory : IVisualFactory
    {
        private IVisualFactory _defaultFactory;
        private GraphControl _control;

        public IVisualFactory DefaultFactory
        {
            get { return _defaultFactory; }
        }

        public PosterViewVisualFactory(GraphControl control)
        {
            _control = control;
            var vf = control.Diagram.Canvas.VisualFactory as PosterViewVisualFactory;
            if (vf == null)
            {
                _defaultFactory = control.Diagram.Canvas.VisualFactory;
            }
            else
            {
                _defaultFactory = vf.DefaultFactory;
            }
        }

        public void BeginRealize()
        {
            _defaultFactory.BeginRealize();
        }

        public void EndRealize()
        {
            _defaultFactory.EndRealize();
        }

        private Visual CreateCircleNodeShape(GraphNode node, bool force)
        {
            if (!force)
            {
                double scale = this._control.Diagram.Scale;
                Rect bounds = node.GetBounds();
                double num2 = scale * bounds.Height;
                if ((num2 < 2.0) && node.HasParentGroups)
                {
                    return null;
                }
            }
            node.SetNodeRadius(20);
            VisualGraphProperties.SetBackground(node, Brushes.Black);
            GraphVisualProperties.SetBackground(node, Brushes.Black);
            VisualGraphProperties.SetForeground(node, Brushes.White);
            GraphVisualProperties.SetForeground(node, Brushes.White);
            GraphObjectExtensions.SetFontSize(node, 20);
            IconLabel label = CreateLabel(this._control, node, "Foreground", Brushes.White);
            var dependencyObject = new CircleNodeShape(label)
            {
                MinWidth = 40.0,
                MinHeight = 30.0,
                CornerRadius = 20.0,
                FocusVisualStyle = (Style)this._control.Resources["NodeFocusStyle"],
                Focusable = true
            };

            var scope = new NameScope();
            NameScope.SetNameScope(dependencyObject, scope);
            label.HorizontalAlignment = HorizontalAlignment.Center;
            label.VerticalAlignment = VerticalAlignment.Center;
            label.Margin = BubbleShape.DefaultLabelMargin;
            dependencyObject.Content = label;
            return dependencyObject;
        }
        internal static IconLabel CreateLabel(GraphControl control, GraphObject label, string foregroundProperty, Brush fallbackForeground)
        {
            ContrastingGraphLabel label2 = new ContrastingGraphLabel(foregroundProperty, true)
            {
                TextWrapping = TextWrapping.Wrap,
                TextTrimming = TextTrimming.CharacterEllipsis
            };
            IconLabel label3 = new IconLabel
            {
                Focusable = false,
                Editable = true,
                Label = label2
            };
            //label3.Committed += new EventHandler<CommittedTextEventArgs>(control.OnEditCommitted);
            //label3.Canceled += new EventHandler(control.OnEditCanceled);
            label3.DefaultForeground = fallbackForeground;
            return label3;
        }
        public System.Windows.Media.Visual Realize(object item, bool force)
        {
            System.Windows.Media.Visual v;
            GraphNode node = item as GraphNode;
            if (node != null)
            {
                if (node.Id.ToString() == "RenderControl")
                {
                    return new RenderControl(this._control.Diagram, node);
                }
                else
                {
                    //return CreateCircleNodeShape(node, false);
                }
            }
            GraphGroup g = item as GraphGroup;
            GraphLink l = item as GraphLink;
            if (g != null && ModularDecomposition.ModuleLevelCategories != null && g.HasCategory(ModularDecomposition.ModuleLevelCategories[0]))
            {
                ModuleGroup mg = new ModuleGroup(_control.Diagram);
                var placeholder = new GroupShapeContentPlaceholder { Margin = new Thickness(5), Name = "PART_ContentPlaceHolder" };
                System.Windows.Markup.INameScope scope = new NameScope();
                NameScope.SetNameScope(mg, scope);
                scope.RegisterName("PART_ContentPlaceHolder", placeholder);
                ((Grid)mg.Content).Children.Add(placeholder);
                v = mg;
            }
            else if (l != null)
            {
                Color seeThrough = new Color();
                seeThrough.A = 10;
                l.SetStroke(new SolidColorBrush(seeThrough));
                v = _defaultFactory.Realize(item, force);
            }
            else if (l != null && l.IsPseudo && l.Target.IsGroup)
            {
                l.SetLinkTargetDecoratorHeight(0.1);
                l.SetLinkTargetDecoratorBaseTipDepth(0.1);
                //Color seeThrough = new Color();
                //seeThrough.A = 0;
                //l.SetStroke(new SolidColorBrush(seeThrough));
                v = _defaultFactory.Realize(item, force);
            }
            else
            {
                v = _defaultFactory.Realize(item, force);
            }

            return v;
        }

        public bool Virtualize(System.Windows.Media.Visual visual)
        {
            return _defaultFactory.Virtualize(visual);
        }
    }
}
